﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using SF.Code.Extension.BusinessHelper;
using SG.Ling.AutoTranslator.Common;
using SG.Ling.AutoTranslator.NLP;

namespace SG.Ling.AutoTranslator.Translation
{
    partial class UserForm
    {
        private readonly IDictionary<string, CultureInfoDisplay> _previousSelectionMapping = new Dictionary<string, CultureInfoDisplay>();

        private IEnumerable<ObjectWithSettings<ComboBox, int>> LanguageSelectors()
        {
            yield return new ObjectWithSettings<ComboBox, int>(comboBoxSource,
                                                               () => _settings.SourceLanguage,
                                                               pVal => _settings.SourceLanguage = pVal);
            yield return new ObjectWithSettings<ComboBox, int>(comboBoxTarget,
                                                               () => _settings.TargetLanguage,
                                                               pVal => _settings.TargetLanguage = pVal);
        }

        private static void SetupLanguageSelector(CultureInfo language, ObjectWithSettings<ComboBox, int> wrapper)
        {
            var box = wrapper.Object;
            box.Items.Add(new CultureInfoDisplay(language));
            box.SelectedIndexChanged +=
                (pSender, pArgs) => wrapper.Setter(Selected(box).Culture.LCID);

            if (language.LCID == wrapper.Getter())
                box.SelectedIndex = box.Items.Count - 1;
        }

        private void SetupLanguageSelectors()
        {
            comboBoxSource.Items.Add(new CultureInfoDisplay(CultureInfo.InvariantCulture));
            var setupComboBoxes =
                from language in Support.Languages
                where !language.Value.IsNeutralCulture
                from selector in LanguageSelectors()
                orderby language.Key
                select new { Language = language.Value, ComboBoxWithSettings = selector };

            foreach (var box in setupComboBoxes)
                SetupLanguageSelector(box.Language, box.ComboBoxWithSettings);

            var ensureSelected =
                from selector in LanguageSelectors()
                let comboBox = selector.Object
                where comboBox.Items.Count > 0
                select new {ComboBox = comboBox, NoneSelected = comboBox.SelectedIndex < 0};

            foreach (var box in ensureSelected)
            {
                if (box.NoneSelected)
                    box.ComboBox.SelectedIndex = 0;

                EnsureSelect(box.ComboBox);
            }
        }

        private void EnsureSelect(ComboBox box)
        {
            Select(box, Selected(box));
        }
        private static CultureInfoDisplay Selected(ComboBox box)
        {
            return (CultureInfoDisplay)box.SelectedItem;
        }
        private void Select(ComboBox box, CultureInfoDisplay culture)
        {
            box.SelectedItem = _previousSelectionMapping[box.Name] = culture;
        }

        private void ComboBoxValueChanged(ComboBox active, ComboBox other)
        {
            if (active.SelectedIndex < 0 || other.SelectedIndex < 0)
                return;


            var justSelected = Selected(active);
            var prevActiveCulture = _previousSelectionMapping[active.Name];

            if (prevActiveCulture.Culture.IsNeutralCulture || justSelected.Culture.IsNeutralCulture)
                return;

            if (justSelected == Selected(other))
            {
                Select(active, justSelected);
                Select(other, prevActiveCulture);
                FlipText();
            }
            else
            {
                var textBoxName = active.Tag as string;
                Control[] controls;
                TextBoxBase textBox;
                if ( textBoxName == null
                    || ((controls = Controls.Find(textBoxName, false)).Length != 1)
                    || (textBox = controls[0] as TextBoxBase) == null)
                    throw new ArgumentException(active.Name + @" has no valid tag", "active");

                textBox.Clear();
            }
        }

        private void FlipLanguages()
        {
            var source = Selected(comboBoxSource);
            var target = Selected(comboBoxTarget);

            if (source == null || source.Culture.IsNeutralCulture) return;
            if (source == target)
                return;

            Select(comboBoxSource, Selected(comboBoxTarget));
            Select(comboBoxTarget, source);

            FlipText();
        }

        private void FlipText()
        {
            var sourceText = _tbEdit.Text;
            _tbEdit.Text = _tbTranslated.Text;
            _tbTranslated.Text = sourceText;
        }
    }
}
